package com.example.birdfriends.controller;

import cn.hutool.core.io.FileTypeUtil;
import com.example.birdfriends.pojo.bird.Bird;
import com.example.birdfriends.pojo.bird.BirdAndAuthor;
import com.example.birdfriends.pojo.bird.BirdFront;
import com.example.birdfriends.pojo.bird.BirdsAndAuthors;
import com.example.birdfriends.pojo.search.SearchContent;
import com.example.birdfriends.pojo.user.User;
import com.example.birdfriends.service.BirdService;
import com.example.birdfriends.utils.convert.ConvertService;
import com.example.birdfriends.utils.files.FileService;
import com.example.birdfriends.utils.result.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Timestamp;
import java.util.*;

@RestController
@RequestMapping("/bird")
public class BirdController {
    @Autowired
    private BirdService birdService = null;
    @Autowired
    Result result = null;
    @Autowired
    ConvertService convertService = null;
    private final Long lineNum = 12L;

    @PostMapping("/findSimpleBirds")  // 检索鸟类的简单数据信息
    public Map<String, Object> findBirds(@RequestBody Long currentPage){
        System.out.println("当前页:"+currentPage);
        Long start = (currentPage-1)*this.lineNum;
        System.out.println("开始查询");
        List<BirdFront> birdFronts = birdService.findBirdNamesAndImages(start, this.lineNum);  // 查找鸟类的名字和图片
        boolean success = birdFronts != null && (!birdFronts.isEmpty());
        if (success){
            BirdsAndAuthors birdsAndAuthors = convertService.findBirdsAndAuthors(birdFronts);
            return result.resultMap(true, "查询成功", birdsAndAuthors);
        }

        return result.resultMap(false, "查询失败，暂未发布词条", birdFronts);
    }

    @PostMapping("/filterBirds")
    public Map<String, Object> filterBirds(@RequestBody SearchContent searchContent){
        searchContent.printSearch();
        String section = searchContent.getSection();
        String name = searchContent.getName();
        int curPage = searchContent.getCurPage();
        long start = (curPage-1) * this.lineNum;

        List<Bird> birds = birdService.findBirdsBySearch(section, name, start, lineNum);
        boolean success = birds != null && (!birds.isEmpty());
        if(success){
            List<BirdFront> birdFronts = convertService.birds2BirdFronts(birds);
            BirdsAndAuthors birdsAndAuthors = convertService.findBirdsAndAuthors(birdFronts);
            return result.resultMap(true, "搜索成功", birdsAndAuthors);
        }

        return result.resultMap(false, "搜索失败，暂无数据", null);
    }

    @PostMapping("/countFilterPageNumber")
    public Map<String, Object> countFilterPageNumber(@RequestBody SearchContent searchContent){
        String section = searchContent.getSection(), name = searchContent.getName();
        int birdNumber = birdService.countBirdsBySearch(section, name);  // 搜索的页数
        boolean success = birdNumber > 0;
        if(success){
            long remain = birdNumber % this.lineNum;
            long pageNumber;
            if(remain == 0){
                pageNumber = (birdNumber / 12) * 10;
            }
            else pageNumber = (birdNumber / 12 + 1) * 10;
            return result.resultMap(true, "查询成功", pageNumber);
        }
        return result.resultMap(false, "查询失败，暂未发布词条", 0);
    }

    @PostMapping("/totalNumber")
    public Map<String, Object> countBirdsNumber(){
        Long birdsNumber = birdService.countBirdsNumber();  // 总共的页数
        boolean success = birdsNumber > 0;
        if(success){
            long remain = birdsNumber % 12;
            long pageNumber;
            if(remain == 0){
                // 整除完
                pageNumber = (birdsNumber / 12) * 10;

            }else pageNumber = (birdsNumber / 12 + 1) * 10;
            return result.resultMap(true, "", pageNumber);
        }

        return result.resultMap(false, "暂未发布词条", 0);
    }

    @PostMapping("/myBirdNumber")
    public Long findMyBirds(@RequestBody User user){
        Long uid = user.getId();
        return birdService.findMyBirdsNumber(uid);
    }

    @PostMapping("/birdSections")
    public Map<String, Object> findBirdSections(){
        List<String> sections = birdService.findBirdSections();
        boolean success = sections != null && (!sections.isEmpty());
        if(success){
            return result.resultMap(true, "查询成功", sections);
        }
        return result.resultMap(false, "查询失败", sections);
    }

    @PostMapping("/info")
    public Map<String, Object> findBirdInfo(@RequestBody BirdFront bird){
        Long bid = bird.getBid();
        Bird bird1 = birdService.findBirdByBid(bid);
        boolean success = bird1 != null;
        if(success){
            String introduction = bird1.getIntroduction();
//            System.out.println("old introduction:"+introduction);
            introduction = introduction.replace("\\n", "\n\n");
//            System.out.println("new introduction:"+introduction);
            bird1.setIntroduction(introduction);
            BirdAndAuthor birdAndAuthor = convertService.findBirdAndAuthor(bird1);
            return result.resultMap(true, "查询成功", birdAndAuthor);
        }

        return result.resultMap(false, "查询失败，未查询到相关信息", null);
    }

    @PostMapping("/myBirdEntry")
    public Map<String, Object> findMyBirdEntry(@RequestBody BirdFront birdFront){
//        System.out.print("info:");birdFront.printBirdFront();
        Long authorId = birdFront.getAuthorId();
        Long curPage = birdFront.getCurPage();
        Long start = (curPage-1) * lineNum;
        List<Bird> birds = birdService.findBirdsByAuthorId(authorId, start, lineNum);
        boolean success = birds != null && (!birds.isEmpty());
        if(success){
            List<BirdFront> birdFronts = convertService.birds2BirdFronts(birds);
            return result.resultMap(true, "查询成功", birdFronts);
        }

        return result.resultMap(false, "查询失败，未找到相关词条", null);
    }

    private final String rootDir = "D:\\bf-files\\springboot-upload\\bird-images";

    @PostMapping("/addMyEntry")
    public Map<String, Object> addMyBirdEntry(@RequestBody BirdFront front){
        // 判断是否已有当前鸟类数据
        String birdname = front.getBirdname();
        String section = front.getSection();

        if(birdname == null || section == null){
            return result.resultMap(false, "添加失败，名称或种类不能为空", null);
        }
        List<Bird> birds = birdService.findBirdByNameAndSection(birdname, section);
        if (!birds.isEmpty()){
            return result.resultMap(false, "添加失败，已有该物种!", null);
        }
        // 暂无当前鸟类信息：前端提供了名称，科属，简介，作者id等信息
        Bird bird = convertService.birdFront2Bird(front);
        Timestamp createAt = new Timestamp(System.currentTimeMillis());
        bird.setCreateAt(createAt);
//        System.out.print("bird：");bird.printBird();
        int add = birdService.addBirdEntry(bird);
        boolean success = add > 0;
        if(success){
            this.bird = bird;
            this.birdIndex = 0;
            this.birdImageList = new ArrayList<>();
            return result.resultMap(true, "添加成功", bird);
        }
        return result.resultMap(false, "添加失败", null);
    }

    @Autowired
    private FileService fileService = null;

    private List<String> birdImageList;  // 因为可能上传多个图片，所以这些图片用链表保存
    private Bird bird;  // 用于存放之前插入的bird数据
    private int birdIndex;
    @PostMapping("/birdFile")
    public Map<String, Object> uploadBirdFile(MultipartFile file) throws IOException {
        InputStream stream = file.getInputStream();
        String type = FileTypeUtil.getType(stream);
        List<String> imagesType = fileService.imageTypes();

        String birdname = bird.getBirdname();;
        String birdDirPath = rootDir + "/" + birdname + "/";
        File parentImageFolder = new File(birdDirPath);
        if(!parentImageFolder.exists()) parentImageFolder.mkdirs();  // 如果文件夹不存在就创建目录

        if(imagesType.contains(type)){
            String imageName = birdname+(this.birdIndex++)+"."+type;
            File savedFile = new File(birdDirPath+ imageName);
            // 图片保存到相应目录下
            file.transferTo(savedFile);

            // 数据库中需要对应路径
            String filePath = "http://localhost:8888/bird-images/"+birdname+"/"+imageName;
            System.out.println("保存的文件："+imageName + " " + filePath);
            if (this.birdImageList == null){
                this.birdImageList = new ArrayList<>();
                this.birdImageList.add(filePath);
            }else this.birdImageList.add(filePath);
        }

        this.bird.setImages(convertService.list2String(this.birdImageList));
        System.out.print("this bird:");this.bird.printBird();

        int update = birdService.updateBirdImageByBid(this.bird);
        boolean success = update > 0;
        if(success){
            return result.resultMap(true, "更新成功", this.bird);
        }
        return result.resultMap(false, "更新失败", this.bird);
    }

    @PostMapping("/deleteMyEntry")
    public Map<String, Object> deleteMyEntry(@RequestBody BirdFront birdFront){
        System.out.print("delete bird:");birdFront.printBirdFront();
        Long bid = birdFront.getBid();
        String birdname = birdFront.getBirdname();
        Long curLoginUid = birdFront.getCurLoginUid(), curPage = birdFront.getCurPage();
        Bird bird1 = birdService.findBirdByBid(bid);
        Long authorId = bird1.getAuthorId();
        if(!curLoginUid.equals(authorId)){
            List<Bird> oldBirds = birdService.findBirdsByAuthorId(curLoginUid, curPage, lineNum);
            return result.resultMap(false, "删除失败，非词条作者无法删除", oldBirds);
        }

        // 允许删除
        int delete = birdService.deleteMyBirdEntry(bid);
        String path = this.rootDir+"/"+birdname;
        fileService.deleteFolder(path);  // 删除文件或文件夹
        boolean success = delete > 0;

        long start = (curPage-1) * this.lineNum;
//        System.out.println(curLoginUid+" "+curPage+" "+start+" "+lineNUm);
        List<Bird> newBirds = birdService.findBirdsByAuthorId(curLoginUid, start, lineNum);
        List<BirdFront> newBirdFronts = convertService.birds2BirdFronts(newBirds);
        if(success){
            return result.resultMap(true, "删除成功", newBirdFronts);
        }
        return result.resultMap(false, "删除失败", newBirdFronts);
    }

    @PostMapping("/deleteMyBirdImage")
    public Map<String, Object> deleteMyBirdImage(@RequestBody BirdFront birdFront){
        Long bid = birdFront.getBid(), curLoginUid = birdFront.getCurLoginUid();
        Bird bird1 = birdService.findBirdByBid(bid);  // 找到当前要删除照片的鸟类
        Long authorId = bird1.getAuthorId();
        if(!authorId.equals(curLoginUid)){
            return result.resultMap(false, "修改失败，非词条作者无法修改", null);
        }

        String deleteImage = birdFront.getDeleteImage();
        List<String> images = convertService.string2List(bird1.getImages());  // 当前的图片
        if(!images.contains(deleteImage)){
            return result.resultMap(false, "没有当前图片，请重新确认", null);
        }

        fileService.removeListElem(images, deleteImage);  // 删除图片，包括列表中的url和文件夹中的图片
        bird1.setImages(convertService.list2String(images));
        System.out.print("删除图片：");bird1.printBird();
        int delete = birdService.updateBirdImageByBid(bird1);
        boolean success = delete > 0;
        if(success){
            BirdFront ans = convertService.bird2BirdFront(birdService.findBirdByBid(bid));
            return result.resultMap(true, "删除图片成功", ans);
        }
        return result.resultMap(false, "删除图片失败", birdFront);
    }

    @PostMapping("/updateMyEntry")
    public Map<String, Object> updateMyBirdEntry(@RequestBody BirdFront birdFront){
        Long bid = birdFront.getBid(), curLoginUid = birdFront.getCurLoginUid();
        Bird oldBird = birdService.findBirdByBid(bid);
        Long authorId = oldBird.getAuthorId();
        // 检查当前登录者是否为帖子作者
        if(!authorId.equals(curLoginUid)){
            return result.resultMap(false, "非词条作者无法修改", birdFront);
        }

        // 修改词条的文本内容
        if(birdFront.getBirdname() != null && !birdFront.getBirdname().equals("")) oldBird.setBirdname(birdFront.getBirdname());
        if(birdFront.getSection() != null && !birdFront.getSection().equals("")) oldBird.setSection(birdFront.getSection());
        if(birdFront.getIntroduction() != null && !birdFront.getIntroduction().equals("")) oldBird.setIntroduction(birdFront.getIntroduction());
        int update = birdService.updateMyBirdEntry(oldBird);  // 修改数据库信息
        boolean success = update > 0;
        if(success){
            this.toUpdateBird = birdService.findBirdByBid(bid);
            BirdFront ans = convertService.bird2BirdFront(this.toUpdateBird);
            this.toUpdateImages = ans.getImages();  // 当前词条现有的图片列表
            this.birdIndex = 0;
            ans.setCurLoginUid(curLoginUid);
            return result.resultMap(true, "修改成功", ans);
        }

        return result.resultMap(false, "修改失败", birdFront);
    }

    private List<String> toUpdateImages;  // 想要添加图片，就需要往现有的图片列表中加入图片
    private Bird toUpdateBird;  // 待修改的鸟类词条

    @PostMapping("/addBirdImage")
    public Map<String, Object> addBirdImage(MultipartFile file) throws IOException {
        // 将当前提交的图片保存到文件夹，并且加入到图片列表中，最后更新数据库
        InputStream stream = file.getInputStream();
        String type = FileTypeUtil.getType(stream);
        List<String> imageType = fileService.imageTypes();
        String birdname = toUpdateBird.getBirdname();  // 新增图片的鸟名

        String parentPath = this.rootDir + '/'+birdname + '/';
        File parentFolder = new File(parentPath);
        if(!parentFolder.exists()) parentFolder.mkdirs();
        if(!imageType.contains(type)){
            return result.resultMap(false, "不支持当前的文件格式", null);
        }
        String filename = birdname + (this.birdIndex++) + '.' +type;  // 文件名
        String filePath = "http://localhost:8888/bird-images/"+birdname+"/"+filename;  // 文件路径
        // 文件路径可能重复，通过修改文件名来保证路径唯一
        while (this.toUpdateImages.contains(filePath)){
            // 如果当前等文件路径已经存在，那么我需要递增下标，以保证路径不互相同
            filename = birdname + (this.birdIndex++) + '.' +type;
            filePath = "http://localhost:8888/bird-images/"+birdname+"/"+filename;
        }

        File savedFile = new File(parentPath+filename);
        this.toUpdateImages.add(filePath);
        file.transferTo(savedFile);  // 保存图片

        System.out.println("添加图片："+filePath);
        this.toUpdateBird.setImages(convertService.list2String(this.toUpdateImages));
        this.toUpdateBird.printBird();
        int add = birdService.updateBirdImageByBid(this.toUpdateBird);
        boolean success = add > 0;
        if(success){
            Bird bird1 = birdService.findBirdByBid(this.toUpdateBird.getBid());
            BirdFront birdFront = convertService.bird2BirdFront(bird1);
            return result.resultMap(true, "添加图片成功", birdFront);
        }

        return result.resultMap(false, "添加图片失败", null);
    }
}
